'''
Created on 24  2013

@author: Dave
'''
from Quoridor_game import QuoridorAction, WHITE, BLACK, TIE, QuoridorState, DIRECTIONS
from game_agent import GameAgent
from my_alpha_beta import AlphaBetaSearch, TimeOutException
import astar
from algorithm import Heuristic
from Quoridor_problem import QuoridorSearchState
from time import clock


class SmartAgent(GameAgent):
    '''
    classdocs
    '''


    def __init__(self,w = 1,v = 0):
        self.w = w
        self.v = v

    def move(self, game_state):
        action = self.alphaBeta.search(game_state)
        self.game_state = game_state
#        print action.route
        return action
    
    def setup(self, player, game_state, turn_time_limit, setup_time_limit):
        self.player = player
        self.turn_time_limit = turn_time_limit
        u = lambda state, start_time: self.utility(state, start_time)
        self.alphaBeta = AlphaBetaSearch(self.player, u, turn_time_limit, self.w, self.v)

        

    #this is in-fact the heuristic value. In this case the heuristic is not very helpful, play with it and see why... 
    def utility(self, state, start_time):
        winner = state.getWinner()
        if winner is None:
            
            
            alg = astar.AStar()
            numWalls = len(state.wallsH) + len(state.wallsV)
            
            whu = 0
#            if self.player == WHITE or state.WallsLeftB > 0:

            for loc in state.locationsW:
                if clock() - start_time > self.turn_time_limit - 0.5:
                    raise TimeOutException()
                if loc:
                    if numWalls < 3:
                        whu += state.brdSize - 1 - loc
                    else:
                        whu += len(alg.find(QuoridorSearchState(state, loc[0], loc[1],WHITE),Manhattan(WHITE)))
            
            bhu = 0
#            if self.player != WHITE or state.WallsLeftW > 0:
            for loc in state.locationsB:
                if clock() - start_time > self.turn_time_limit - 0.5:
                    raise TimeOutException()   
                if loc:
                    if numWalls < 3:
                        bhu += loc
                    else:
                        bhu += len(alg.find(QuoridorSearchState(state, loc[0], loc[1],BLACK),Manhattan(BLACK)))
           
            if self.player == WHITE:
                return bhu - whu
            else:
                return whu - bhu
            
        elif winner == self.player:
            return 100000
        elif winner == TIE:
            return 0
        else:
            return -100000

class Manhattan(Heuristic):
    
    def __init__(self, player):
        self.player = player
    
    def evaluate(self, problem_state):
        ps = problem_state
        if (self.player == WHITE):
            return ps.qstate.brdSize - 1 - ps.x
        else:
            return ps.x
            